package com.hy.frame.net

import com.google.gson.Gson
import com.google.gson.JsonParser
import com.hy.frame.util.JsonUtil
import com.hy.frame.util.MyLog
import io.reactivex.Observer
import io.reactivex.disposables.Disposable
import okhttp3.ResponseBody


/**
 * NormalObserver
 * @author
 * @time 18-10-25 下午12:02
 * @desc 如果需要去掉 公有code或者msg请继承重写onNext
 */
open class NormalObserver<T> : Observer<ResponseBody> {

    protected var disposable: Disposable? = null
    protected var mListener: ICallback<T>? = null
    protected var mListListener: ICallback<MutableList<T>>? = null
    protected var cls: Class<T>? = null
    protected var isTemplate: Boolean = true
    protected var tCode = "code"
    protected var tMsg = "msg"
    protected var tData = "data"
    protected var tCodeSucces = 1

    fun listener(listener: ICallback<T>?, cls: Class<T>?): NormalObserver<T> {
        this.mListener = listener
        this.cls = cls
        return this
    }

    fun listListener(listener: ICallback<MutableList<T>>?, cls: Class<T>?): NormalObserver<T> {
        this.mListListener = listener
        this.cls = cls
        return this
    }

    fun template(
        template: Boolean = true,
        code: String = "code",
        msg: String = "msg",
        data: String = "data",
        codeSuccess: Int = 1
    ): NormalObserver<T> {
        this.isTemplate = template
        this.tCode = code
        this.tCodeSucces = codeSuccess
        this.tData = data
        this.tMsg = msg
        return this
    }

    override fun onComplete() {
        MyLog.d(javaClass, "onComplete")
    }

    override fun onSubscribe(d: Disposable) {
        this.disposable = d
    }

    @Suppress("UNCHECKED_CAST")
    override fun onNext(body: ResponseBody) {
        this.disposable?.dispose()
        var code = 1//0异常 1成功
        var msg = ""

        // 1. 通用模板
        val data = body.string() ?: ""
        MyLog.d(javaClass, "onNext $data")
        if (cls == null || (mListener == null && mListListener == null)) {
            msg = "未配置listener"
            onError(code, msg)
            return
        }
        var any: Any? = null
        try {
            if (!isTemplate) {
                //直接转换
                when (cls) {
                    String::class.java -> any = data
                    Boolean::class.java -> any = data.toBoolean()
                    Int::class.java -> any = data.toInt()
                    Double::class.java -> any = data.toDouble()
                    Float::class.java -> any = data.toFloat()
                    Long::class.java -> any = data.toLong()
                    else -> {
                        val json = JsonParser().parse(data)
                        when {
                            json.isJsonObject -> any = JsonUtil.getObjectFromJson(json, cls!!)
                            json.isJsonArray -> any = JsonUtil.getListFromJson(json, cls!!)
                        }
                    }
                }
            } else {
                val json = JsonParser().parse(data)
                //使用模板
                if (json.isJsonObject) {
                    val obj = json.asJsonObject
                    if (obj.has(tCode)) {
                        code = obj.get(tCode).asInt
                    }
                    if (obj.has(tMsg)) {
                        msg = obj.get(tMsg).asString
                    }
                    if (code == tCodeSucces) {
                        if (obj.has(tData)) {
                            val element = obj.get(tData)
                            if (mListListener != null) {
                                any = JsonUtil.getListFromJson(element, cls!!)
                            } else {
                                when {
                                    element.isJsonObject -> any = JsonUtil.getObjectFromJson(element, cls!!)
                                    element.isJsonPrimitive -> when (cls) {
                                        String::class.java -> any = element.asString
                                        Boolean::class.java -> any = element.asBoolean
                                        Int::class.java -> any = element.asInt
                                        Double::class.java -> any = element.asDouble
                                        Float::class.java -> any = element.asFloat
                                        Long::class.java -> any = element.asLong
                                    }
                                    else -> any = Gson().fromJson(element, cls)
                                }
                            }
                        }
                    }
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
            MyLog.e("数据异常$e")
            code = -1
            msg = "数据异常，请稍后重试"
        }
        if (code == 1) {
            if (mListListener != null) {
                mListListener?.onSuccess(any as MutableList<T>?, msg)
            } else if (mListener != null) {
                mListener?.onSuccess(any as T?, msg)
            }
            return
        }
        onError(code, msg)
    }

    override fun onError(e: Throwable) {
        MyLog.e("onError$e")
        this.disposable?.dispose()
        onError(-1, "网络异常，请稍后重试")
    }

    private fun onError(code: Int, msg: String?) {
        if (mListListener != null) {
            mListListener?.onError(code, msg)
        } else if (mListener != null) {
            mListener?.onError(code, msg)
        }
    }

    interface ICallback<T> {
        fun onSuccess(obj: T?, msg: String?)
        fun onError(errorCode: Int, msg: String?)
    }
}